#include "EPubBasicEncryptionImp.h"
#include "EPubUtil.h"

EPubPointer<IEPubBuffer> EPubBasicEncryptionImp::Serialize() const
{
	return NULL;
}

EPUB_Result EPubBasicEncryptionImp::Deserialize(const EPubPointer<IEPubBuffer> buffer)
{
	EPUB_Result ret = EPUB_SUCCESS;
	m_EncryptedDataList.clear();

	if(!buffer) {
		return -1;
	}

	TiXmlDocument doc;
	doc.Parse((const char *)buffer->GetBuffer());

	const TiXmlElement *elem_data = NULL;

	EPubPointer<EPubEncryptedDataImp> data(new EPubEncryptedDataImp);

	for(EPub_Xml_Element(&doc, "encryption>enc:EncryptedData", &elem_data);
		elem_data;
		elem_data = elem_data->NextSiblingElement("enc:EncryptedData"))
	{
		const TiXmlElement *elem_temp = NULL;
		std::string algorithm;
		std::string key_name;
		std::string uri;

		EPub_Xml_Element(elem_data, "enc:EncryptionMethod", &elem_temp);
		EPub_Xml_Attribute(elem_temp, "Algorithm", algorithm);
		data->SetAlgorithm(GetEncryptionMethod(algorithm));

		if(EPUB_SUCCEEDED(EPub_Xml_Element(elem_data, "ds:KeyInfo>ds:KeyName", &elem_temp))) {
			EPub_Xml_Text(elem_temp, key_name);
			data->SetKeyInfo(key_name.c_str());
		}

		if(EPUB_SUCCEEDED(EPub_Xml_Element(elem_data, "enc:CipherData>enc:CipherReference", &elem_temp))) {
			
			EPub_Xml_Attribute(elem_temp, "URI", uri);
			data->SetCipherData(uri.c_str());
		}

		m_EncryptedDataList[uri] = data;
	}
	
	return ret;
}

const EPubPointer<IEPubEncryptedData> EPubBasicEncryptionImp::GetEncryptedData(const char *uri) const
{
	EncryptedDataList::const_iterator pos = m_EncryptedDataList.find(uri);
	if(pos != m_EncryptedDataList.end()) {
		return pos->second.Cast<IEPubEncryptedData>();
	}
	return NULL;
}

EPUB_EncryptionMethod EPubBasicEncryptionImp::GetEncryptionMethod(const std::string &ns)
{
	if(_stricmp(ns.c_str(), EPUB_EANS_AES128) == 0) {
		return EPUB_EM_AES128;
	} else if(_stricmp(ns.c_str(), EPUB_EANS_AES128_CBC) == 0) {
		return EPUB_EM_AES128_CBC;
	}

	return EPUB_EM_UNKNOWN;
}